/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package fxbattle.client.model;

import edu.stsci.CoSI.CosiBoolean;
import edu.stsci.CoSI.CosiInt;
import edu.stsci.CoSI.CosiObject;
import edu.stsci.CoSI.collections.CosiMap;
import edu.stsci.CoSI.collections.CosiSet;
import java.awt.Color;
import java.util.Collections;
import java.util.Set;

/**
 *
 * @author spina
 */
public class BattleHex {

	public static final int MAX_HEX_ELEVATION = 10;
	
    // Directions present in the set are directions that troops should head. If the set
    // is empty, then troops stay put.
    //private Map<Player, Set<Direction>> flowPaths = new HashMap<Player, Set<Direction>>();
    private final Set<Direction> flowPaths = CosiSet.enumSetNoneOf(Direction.class);
    private CosiObject<Army> fOccupying = new CosiObject<Army>(Army.no_army);
    private final Location fLoc;
    // Has a maximum of 10.
    private final CosiInt fElevation = new CosiInt(0);
    
    //TODO Make this a CosiEnumMap.
    private final CosiMap<Direction, BattleHex> fAdjacentHexes = CosiMap.hashMap();
    
    private final CosiBoolean fIsBase = new CosiBoolean(false);

    public BattleHex(Location iLoc){
    	fLoc = iLoc;
    }

    public BattleHex(int x, int y) {
    	this(Location.getLocation(x, y));
	}

	public BattleHex getAdjacentHex(Direction iDirectionToGo){
    	if(iDirectionToGo == null){
    		throw new NullPointerException();
    	}
    	BattleHex lHex = fAdjacentHexes.get(iDirectionToGo);
    	if(lHex == null){
    		lHex = BoundaryHex.getBoundary(iDirectionToGo.goFrom(getLocation()));
    		fAdjacentHexes.put(iDirectionToGo, lHex);
    	}
    	return lHex;
    }
	
	public void toggleFlowPathActivity(Direction iDir){
		setFlowPathActivity(iDir, ! isFlowPathActive(iDir));
	}
	
	public void setFlowPathActivity(Direction iDir, boolean iIsActive){
		if(iIsActive){
			activatePath(iDir); 
		} else {
			deactivatePath(iDir);
		}
	}
    
    public void setAdjacentHex(Direction iDirection, BattleHex iNeighbor){
    	fAdjacentHexes.put(iDirection, iNeighbor);
    }
    
    public void setElevation(int iElevation) {
    	fElevation.set(iElevation);
    }
    
    public void setIsBase(boolean iIsBase){
    	fIsBase.set(iIsBase);
    }
    
    public boolean isBase(){ return fIsBase.get(); }
    public Location getLocation() { return fLoc; }
    public int getX(){ return getLocation().getX(); }
    public int getY(){ return getLocation().getY(); }
    public int getElevation(){ return fElevation.get(); }
    public double getElevationAsPercentage() { return ((double) getElevation()) / MAX_HEX_ELEVATION; }

    public Color getColor(){
        return getControllingArmy().getOwner().getColor();
    }

    public void conquered(Army iArmy){
        fOccupying.set(iArmy);
    }

    public Set<Direction> getFlowPaths(){
        return Collections.unmodifiableSet(flowPaths);
    }

    public boolean canActivateFlow(Direction iDirectionToChange){
//    	System.out.println("x = " + getX() + " y = " + getY());
    	return ! (getAdjacentHex(iDirectionToChange) instanceof BoundaryHex);
    }
    
    public boolean isFlowPathActive(Direction iAmIActive){
    	return flowPaths.contains(iAmIActive);
    }
        
    private void activatePath(Direction iAttackInThisDir){
    	if(canActivateFlow(iAttackInThisDir)){
    		flowPaths.add(iAttackInThisDir);
    	}
    }
    
    private void deactivatePath(Direction iDontAttack){
    	flowPaths.remove(iDontAttack);
    }

    public Army getControllingArmy(){
        return fOccupying.get();
    }

    @Override
    public String toString() {
    	return getLocation() + " controlling army: " + getControllingArmy();
    }
    
}
